$:.unshift File.join(File.dirname(__FILE__),"..","lib")
require "test/unit"
require "find"
require "fileutils"
require "create_tree.rb"
require "file_deleter.rb"
require "filter_generator.rb"
require "pathname.rb"
class TestFileDeleter < Test::Unit::TestCase
  
  def setup
    @topdir = "topdir"
    @checktime = "2008-12-30"
    
    @testdir = {@topdir =>[
      "a1",
      {"a2" => ["a2a1",
        {"a2a2" =>["a2a2a1","a2a2a2"]}  
        ]},
      {"a3" => ["a3a1","a3a2"]},
      {"a4" =>[]}
      ]}
    @fileseparator = File::SEPARATOR
    @dir = ".."+@fileseparator+@topdir+@fileseparator
    @fileDeleter = FileDeleter.new(@dir)
    CreateTree.new().create_tree(@testdir)  
    File.utime(Time.mktime(2008,1,1),Time.mktime(2008,12,1),@dir+"a1")
    File.utime(Time.mktime(2008,1,1),Time.mktime(2009,1,1),@dir+"a2")
    File.utime(Time.mktime(2008,1,1),Time.mktime(2008,12,1),@dir+"a2"+@fileseparator+"a2a1")
    File.utime(Time.mktime(2008,1,1),Time.mktime(2009,1,1),@dir+"a2"+@fileseparator+"a2a2")
    File.utime(Time.mktime(2008,1,1),Time.mktime(2009,1,1),@dir+"a2"+@fileseparator+"a2a2"+@fileseparator+"a2a2a1")
    File.utime(Time.mktime(2008,1,1),Time.mktime(2008,12,1),@dir+"a2"+@fileseparator+"a2a2"+@fileseparator+"a2a2a2")
    File.utime(Time.mktime(2008,1,1),Time.mktime(2008,12,1),@dir+"a3")
    File.utime(Time.mktime(2008,1,1),Time.mktime(2008,12,1),@dir+"a3"+@fileseparator+"a3a1")
    File.utime(Time.mktime(2008,1,1),Time.mktime(2008,12,1),@dir+"a3"+@fileseparator+"a3a2")
    File.utime(Time.mktime(2008,1,1),Time.mktime(2009,1,1),@dir+"a4")
  end
  
  
  def test_filechangedafter
    assert_equal(true,@fileDeleter.isModifiedBefore?(@dir+"a1",@checktime))
    assert_equal(false,@fileDeleter.isModifiedBefore?(@dir+"a2",@checktime))
    assert_equal(true,@fileDeleter.isModifiedBefore?(@dir+"a2"+@fileseparator+"a2a1",@checktime))
    assert_equal(false,@fileDeleter.isModifiedBefore?(@dir+"a2"+@fileseparator+"a2a2"+@fileseparator+"a2a2a1",@checktime))
    assert_equal(true,@fileDeleter.isModifiedBefore?(@dir+"a2"+@fileseparator+"a2a2"+@fileseparator+"a2a2a2",@checktime))
    assert_equal(true,@fileDeleter.isModifiedBefore?(@dir+"a3",@checktime))
    assert_equal(false,@fileDeleter.isModifiedBefore?(@dir+"a4",@checktime))
  end
  
  def test_deleteFileAndDirModifiedBeforeSpecifiedDate
    @fileDeleter.deleteFileAndDirModifiedBeforeSpecifiedDate(@checktime)
    assert_equal(false,File.exists?(@dir+"a1"))
    assert_equal(true,File.exists?(@dir+"a2"))
    assert_equal(false,File.exists?(@dir+"a2"+@fileseparator+"a2a1"))
    assert_equal(true,File.exists?(@dir+"a2"+@fileseparator+"a2a2"))
    assert_equal(true,File.exists?(@dir+"a2"+@fileseparator+"a2a2"+@fileseparator+"a2a2a1"))
    assert_equal(false,File.exists?(@dir+"a2"+@fileseparator+"a2a2"+@fileseparator+"a2a2a2"))
    assert_equal(false,File.exists?(@dir+"a3"))
    assert_equal(true,File.exists?(@dir+"a4"))
  end
  
  def test_delete_file_with_modified_time_unchanged
    @fileDeleter.deleteFileAndDirModifiedBeforeSpecifiedDate(@checktime)
    assert_equal(File.mtime(@dir+"a2").year, 2009)
    assert_equal(File.mtime(@dir+"a2").month, 1)
    assert_equal(File.mtime(@dir+"a2").day, 1)
  end
  
  class MockFileDeleter < FileDeleter
    def deleteByTimeRange(time)
      time
    end
  end
  
  def test_deleteFileAndDirModified_5_month_ago
    @fileDeleter = MockFileDeleter.new(@dir)
    assert_equal("5m",@fileDeleter.deleteByTimeRange("5m"))
  end
  
  def test_deleteFileAndDirWithDefaultTimeRange
    @fileDeleter = MockFileDeleter.new(@dir)
    assert_equal("1m", @fileDeleter.deleteFileAndDirWithDefaultTimeRange())
  end
  
  class MockRelativePathFilterGenerator < FilterGenerator
    def generateFilter
      foldersToBeKept << "a2/a2a2"
      foldersToBeKept << "a3"
    end
  end
  
  def test_inFilterList
    filter = MockRelativePathFilterGenerator.new
    @fileDeleter = FileDeleter.new(@dir,filter)
    assert_equal(true,@fileDeleter.inFilterList?(@dir+"a2"))
    assert_equal(false,@fileDeleter.inFilterList?(@dir+"a2/a2a1"))
    assert_equal(true,@fileDeleter.inFilterList?(@dir+"a2/a2a2"))
    assert_equal(true,@fileDeleter.inFilterList?(@dir+"a2/a2a2/a2a2a1"))  
    assert_equal(true,@fileDeleter.inFilterList?(@dir+"a3"))
    assert_equal(true,@fileDeleter.inFilterList?(@dir+"a3/a3a1"))
  end
  
  def test_delete_file_should_ignore_those_in_filter_list
    filter = MockRelativePathFilterGenerator.new
    @fileDeleter = FileDeleter.new(@dir,filter)
    @fileDeleter.deleteFileAndDirModifiedBeforeSpecifiedDate(@checktime)
    
    assert_equal(false,File.exists?(@dir+"a1"))
    assert_equal(true,File.exists?(@dir+"a2"))
    assert_equal(false,File.exists?(@dir+"a2"+@fileseparator+"a2a1"))
    assert_equal(true,File.exists?(@dir+"a2"+@fileseparator+"a2a2"))
    assert_equal(true,File.exists?(@dir+"a2"+@fileseparator+"a2a2"+@fileseparator+"a2a2a1"))
    assert_equal(true,File.exists?(@dir+"a2"+@fileseparator+"a2a2"+@fileseparator+"a2a2a2"))
    assert_equal(true,File.exists?(@dir+"a3"))
    assert_equal(true,File.exists?(@dir+"a4"))
  end
  
  def test_generate_absolute_path_filters
    filter = MockRelativePathFilterGenerator.new
    @fileDeleter = FileDeleter.new(@dir, filter)
    absolutePathFilters = @fileDeleter.generateAbsolutePathFilters()
    assert_equal(true,absolutePathFilters.include?(@dir+"a2/a2a2"))
    assert_equal(true,absolutePathFilters.include?(@dir+"a3"))
  end
  
  def teardown
    Dir.chdir("..")
    @testdir.each_pair {|key,value| FileUtils.rm_r(key)}
    Dir.chdir("test")
  end
end